package com.example.pcl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.pcl.constant.MessageConstants;
import com.example.pcl.exception.ObjectException;
import com.example.pcl.mapper.UsersMapper;
import com.example.pcl.pojo.dto.NotificationsDTO;
import com.example.pcl.pojo.dto.NotificationsFilterDTO;
import com.example.pcl.pojo.entity.Notifications;
import com.example.pcl.mapper.NotificationsMapper;
import com.example.pcl.pojo.vo.NotificationsVO;
import com.example.pcl.result.PageResult;
import com.example.pcl.service.INotificationsService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.pcl.utils.ThreadLocalUtil;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 通知表，存储与用户和心理咨询师相关的各种预约通知 服务实现类
 * </p>
 *
 * @author xx
 * @since 2024-12-17
 */
@Service
@RequiredArgsConstructor
public class NotificationsServiceImpl extends ServiceImpl<NotificationsMapper, Notifications> implements INotificationsService {


    private final NotificationsMapper notificationsMapper;


    private final UsersMapper userMapper;

    @Override
    public PageResult<NotificationsVO> listNotifications(@NotNull NotificationsFilterDTO filterDTO) {

        Page<Notifications> page = new Page<>(filterDTO.getPageNum(), filterDTO.getPageSize());
        LambdaQueryWrapper<Notifications> queryWrapper = new LambdaQueryWrapper<>();

        if (filterDTO.getRecipientId() != null) {
            queryWrapper.eq(Notifications::getRecipientId, filterDTO.getRecipientId());
        }
        if (filterDTO.getNotificationStatus() != null) {
            queryWrapper.eq(Notifications::getNotificationStatus, filterDTO.getNotificationStatus());
        }
        queryWrapper.orderByDesc(Notifications::getCreatedAt);
        Page<Notifications> resultPage = notificationsMapper.selectPage(page, queryWrapper);

        List<NotificationsVO> voList = resultPage.getRecords().stream().map(notification -> {
            NotificationsVO vo = new NotificationsVO();
            BeanUtils.copyProperties(notification, vo);
            vo.setRecipientName(userMapper.selectById(notification.getRecipientId()).getUsername());
            vo.setNotificationStatus(
                    switch (notification.getNotificationStatus()) {
                        case 0 -> "未读";
                        case 1 -> "已读";
                        default -> "已删除";
                    }
            );
            return vo;
        }).toList();

        return new PageResult<>(resultPage.getTotal(), voList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addNotification(NotificationsDTO notificationsDTO) {
        Notifications notification = new Notifications();
        notification.setNotificationStatus(Notifications.UNREAD);
        BeanUtils.copyProperties(notificationsDTO, notification);
        int rows = notificationsMapper.insert(notification);
        if (rows <= 0) {
            throw new ObjectException(MessageConstants.ADD_ERR);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateNotification(NotificationsDTO notificationsDTO) {
        Notifications notification = new Notifications();
        BeanUtils.copyProperties(notificationsDTO, notification);
        int rows = notificationsMapper.updateById(notification);
        if (rows <= 0) {
            throw new ObjectException(MessageConstants.UPDATE_ERR);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteNotification(Integer notificationId) {
        int rows = notificationsMapper.deleteById(notificationId);
        if (rows <= 0) {
            throw new ObjectException(MessageConstants.DELETE_ERR);
        }
    }

    @Override
    public NotificationsVO finById(Integer id) {
        Notifications notification = getById(id);
        return BeanUtil.copyProperties(notification, NotificationsVO
                .class).setRecipientName(userMapper.selectById(notification.getRecipientId()).getUsername());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void batchRead() {
        // 获取当前用户ID
        Integer id = ThreadLocalUtil.getId();

        // 查找当前用户的未读通知
        List<Notifications> list = list(new LambdaQueryWrapper<Notifications>()
                .eq(Notifications::getRecipientId, id)
                .eq(Notifications::getNotificationStatus, Notifications.UNREAD));

        // 如果未读通知列表不为空，批量更新为已读
        if (CollectionUtil.isNotEmpty(list)) {
            list.forEach(notification -> {
                notification.setNotificationStatus(Notifications.READ); // 设置为已读
            });
            // 批量更新通知
            updateBatchById(list);
        }
    }

}
